﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using ExtractItAll.Core;
using ExtractItAll.Extractors;
using ExtractItAll.Forms;

namespace ExtractItAll
{
  internal static class Program
  {
    private static DateTime _buildTime;
    private static List<BaseExtractor> _extractorList;
    private static System.Threading.Mutex _m;
    private static PasswordList _passwords;
    private static ExtractItAllSettings _settings;
    private static TaskManager _tasks;
    private static FileVersionInfo _versionInfo;

    public static TaskManager Tasks
    {
      get { return _tasks ?? (_tasks = new TaskManager()); }
    }

    public static PasswordList Passwords
    {
      get { return _passwords ?? (_passwords = new PasswordList()); }
    }

    public static ExtractItAllSettings Settings
    {
      get { return _settings ?? (_settings = new ExtractItAllSettings()); }
      set { _settings = value; }
    }

    public static List<BaseExtractor> ExtractorList
    {
      get { return _extractorList ?? (_extractorList = new List<BaseExtractor>()); }
    }

    private static string SettingsFile
    {
      get { return Path.Combine(Application.StartupPath, "settings.xml"); }
    }

    private static string PasswordFile
    {
      get { return Path.Combine(Application.StartupPath, "password.txt"); }
    }

    public static FileVersionInfo VersionInfo
    {
      get
      {
        if (_versionInfo == null)
        {
          _versionInfo = FileVersionInfo.GetVersionInfo(Application.ExecutablePath);
        }

        return _versionInfo;
      }
    }

    public static DateTime BuildTime
    {
      get
      {
        if (_buildTime == DateTime.MinValue)
        {
          FileInfo appExe = new FileInfo(Application.ExecutablePath);
          _buildTime = appExe.LastWriteTimeUtc;
        }

        return _buildTime;
      }
    }

    public static string ProjectWebsite
    {
      get { return "http://code.google.com/p/extract-it-all/"; }
    }

    public static string UpdateFile
    {
      get { return "http://extract-it-all.googlecode.com/git/ExtractItAll/update.xml"; }
    }


    private static bool IsAlreadyRunning()
    {
      bool firstInstance;
      _m = new System.Threading.Mutex(true, "{0f9cfb8f-0622-4b33-9379-96cc74610885}", out firstInstance);

      if (!firstInstance)
      {
        MessageBox.Show("Another instance of this application is already opened!", "Application already running",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
        return true;
      }

      return !firstInstance;
    }


    /// <summary>
    /// Der Haupteinstiegspunkt für die Anwendung.
    /// </summary>
    [STAThread]
    private static void Main()
    {
      // Allow only one instance running of this application.
      if (IsAlreadyRunning())
        return;

      // Load settings and password file
      if (!File.Exists(SettingsFile))
        new ExtractItAllSettings().SaveAppSettings(SettingsFile);
      Settings = (ExtractItAllSettings)new ExtractItAllSettings().GetAppSettings(SettingsFile);
      Passwords.Load(PasswordFile);

      // detect the available extractor types
      foreach (Type t in Assembly.GetExecutingAssembly().GetTypes())
      {
        if (t.BaseType == null) continue;

        if (t.BaseType.Name == typeof (BaseExtractor).Name)
        {
          ExtractorList.Add((BaseExtractor)Activator.CreateInstance(t));
        }
      }
      ExtractorList.Sort(new ExtractorComparer());

      // do update check, if enabled
      if (Settings.UpdateCheckOnStartup)
      {
        if (!Settings.UpdateCheckOnlyOnceADay || (
                                                   Settings.UpdateCheckOnlyOnceADay &&
                                                   DateTime.Now.Subtract(Settings.LastUpdateCheck) >
                                                   new TimeSpan(1, 0, 0, 0)
                                                 ))
          Settings.LastUpdateCheck = DateTime.Now;

        UpdateCheck.SilentCheck(UpdateFile);
      }

      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Application.Run(new MainForm());

      Tasks.Stop();

      // save settings and passwords
      Passwords.Save(PasswordFile);
      Settings.SaveAppSettings(SettingsFile);
    }
  }
}